﻿using System.Collections;
using System.Collections.Generic;
using UnityEngine;
namespace EELibrary.Collision2D
{
    public class Collision2DTool 
    {

        // 参考地址:https://zhuanlan.zhihu.com/p/23903445
        // 扇形与圆盘相交测试
        // a 扇形圆心
        // u 扇形方向（单位矢量）
        // theta 扇形扫掠半角 
        // l 扇形边长
        // c 圆盘圆心
        // r 圆盘半径
        static public bool IsSectorDiskIntersect(
            Vector2 a, Vector2 u, float theta, float l,
            Vector2 c, float r)
        {
            // 1. 如果扇形圆心和圆盘圆心的方向能分离，两形状不相交
            Vector2 d = c - a;
            float rsum = l + r;
            if (d.sqrMagnitude > rsum * rsum)
                return false;

            // 2. 计算出扇形局部空间的 p
            float px = Vector2.Dot(d, u);
            float py = Mathf.Abs(Vector2.Dot(d, new Vector2(-u.y, u.x)));

            // 3. 如果 p_x > ||p|| cos theta，两形状相交
            if (px > d.magnitude * Mathf.Cos(theta))
                return true;

            // 4. 求左边线段与圆盘是否相交
            Vector2 q = l * new Vector2(Mathf.Cos(theta), Mathf.Sin(theta));
            Vector2 p = new Vector2(px, py);
            return SegmentPointSqrDistance(Vector2.zero, q, p) <= r * r;
        }

        // 参考地址:http://blog.csdn.net/zaffix/article/details/25077835
        // 圆与矩形碰撞检测
        // 圆心circle_center, 半径circle_raidus, 矩形中心rect_center, 矩形上边中心rect_width_center, 矩形右边中心rect_length_center
        static public bool IsCircleIntersectRectangle(Vector2 rect_center, Vector2 rect_width_center, Vector2 rect_length_center, Vector2 circle_center, float circle_raidus)
        {
            float w1 = Vector2.Distance(rect_center, rect_length_center);
            float h1 = Vector2.Distance(rect_center, rect_width_center);
            float w2 = DistanceFromPointToLine(circle_center, rect_center, rect_width_center);
            float h2 = DistanceFromPointToLine(circle_center, rect_center, rect_length_center);


            if (w2 > w1 + circle_raidus)
                return false;
            if (h2 > h1 + circle_raidus)
                return false;

            if (w2 <= w1)
                return true;
            if (h2 <= h1)
                return true;

            return (w2 - w1) * (w2 - w1) + (h2 - h1) * (h2 - h1) <= circle_raidus * circle_raidus;
        }


        // 计算线段与点的最短平方距离
        // x0 线段起点
        // u  线段方向至末端点
        // x  任意点
        static public float SegmentPointSqrDistance(Vector2 x0, Vector2 u, Vector2 x)
        {
            float t = Vector2.Dot(x - x0, u) / u.sqrMagnitude;
            return (x - (x0 + Mathf.Clamp(t, 0, 1) * u)).sqrMagnitude;
        }

        // 计算两点之间的距离
        static public float DistanceBetweenTwoPoints(float x1, float y1, float x2, float y2)
        {
            //return sqrt((x2 - x1) * (x2 - x1) + (y2 - y1) * (y2 - y1));
            return Mathf.Sqrt((x2 - x1) * (x2 - x1) + (y2 - y1) * (y2 - y1));
        }

        // 计算点(x, y)到经过两点(x1, y1)和(x2, y2)的直线的距离
        static public float DistanceFromPointToLine( Vector2 point, Vector2 x1, Vector2 x2)// float x, float y, float x1, float y1, float x2, float y2)
        {
            float a = x2.y - x1.y;
            float b = x1.x - x2.x;
            float c = x2.x * x1.y - x1.x * x2.y;

            //assert(fabs(a) > 0.00001f || fabs(b) > 0.00001f);
            
            return Mathf.Abs(a * point.x + b * point.y + c) / Mathf.Sqrt(a * a + b * b);
        }
    }

}

